﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Timers;
using System.Threading.Tasks;

namespace Atom.Tool
{
    public delegate void TimeEvent();
    public class ScheduleUtil
    {
        private static ScheduleUtil util;
        public static ScheduleUtil Instance { get { if (util == null) { util = new ScheduleUtil(); } return util; } }
        Timer timer;

        private ConcurrentInteger index = new ConcurrentInteger();
        //等待执行的任务表
        private Dictionary<int, TimeTaskModel> mission = new Dictionary<int, TimeTaskModel>();
        //等待移除的任务列表
        private List<int> removelist = new List<int>();

        private ScheduleUtil()
        {
            timer = new Timer(14);
            timer.Elapsed += callback;
            timer.Start();
        }

        void callback(object sender, ElapsedEventArgs e)
        {
            lock (mission)
            {
                lock (removelist)
                {
                    foreach (int item in removelist)
                    {
                        mission.Remove(item);
                    }
                    removelist.Clear();
                    foreach (TimeTaskModel item in mission.Values)
                    {
                        if (item.Time <= DateTime.Now.Ticks)
                        {
                            item.Run();
                            removelist.Add(item.Id);
                        }
                    }
                }
            }
        }
        /// <summary>
        /// 任务调用  毫秒
        /// </summary>
        /// <param name="task"></param>
        /// <param name="delay"></param>
        /// <returns></returns>
        public int Schedule(TimeEvent task, long delay)
        {
            //毫秒转微秒
            return Schedulemms(task, delay * 1000 * 10);
        }
        /// <summary>
        /// 微秒级时间轴
        /// </summary>
        /// <param name="task"></param>
        /// <param name="delay"></param>
        /// <returns></returns>
        private int Schedulemms(TimeEvent task, long delay)
        {
            lock (mission)
            {
                int id = index.GetAndAdd();
                TimeTaskModel model = new TimeTaskModel(id, DateTime.Now.Ticks + delay, task);
                mission.Add(id, model);
                return id;
            }
        }

        public void RemoveMission(int id)
        {
            lock (removelist)
            {
                removelist.Add(id);
            }
        }


        public int Schedule(TimeEvent task, DateTime time)
        {
            long t = time.Ticks - DateTime.Now.Ticks;
            t = Math.Abs(t);
            return Schedulemms(task, t);
        }


        public int TimeSchedule(TimeEvent task, long time)
        {
            long t = time - DateTime.Now.Ticks;
            t = Math.Abs(t);
            return Schedulemms(task, t);
        }

    }
}